<?php

namespace app\admin\service;

use app\admin\model\Menu;
use app\common\controller\Send;
use gmars\rbac\model\Permission;
use gmars\rbac\Rbac AS RbacBase;
use think\facade\Cache;
use think\facade\Session;

class Rbac
{
    use Send;

    public $_sessionName = 'gmars_rbac_permission_name';
    private $_permissionCachePrefix = "_RBAC_PERMISSION_CACHE_";

    /**
     * 获取用户权限并缓存
     * @param $id
     * @param int $timeOut
     * @return array
     */
    public function cachePermission($id, $timeOut = 3600)
    {
        try {
            $rbac = new RbacBase();
            $return = $rbac->cachePermission($id, $timeOut);
            return self::sendResult(self::$okCode, $return);
        } catch (\Exception $e) {
            return self::sendResult(600, [], $e->getMessage());
        }
    }

    /**
     * 检查用户有没有权限执行某操作
     * @param $path
     * @return array
     */
    public function can($path)
    {
        try {
            $rbac = new RbacBase();
            $return = $rbac->can($path);
            $code = ($return === true) ? self::$okCode : 601;
            return self::sendResult($code);
        } catch (\Exception $e) {
            return self::sendResult(600, [], $e->getMessage());
        }
    }

    /**
     * @param array $where
     * @return array
     */
    public function getPermissionCategory($where = [])
    {
        try {
            $rbac = new RbacBase();
            $return = $rbac->getPermissionCategory($where);
            return self::sendResult(self::$okCode, $return);
        } catch (\Exception $e) {
            return self::sendResult(600, [], $e->getMessage());
        }
    }

    /**
     * @param $data
     * @return array
     */
    public function savePermissionCategory($data)
    {
        try {
            $rbac = new RbacBase();
            $return = $rbac->savePermissionCategory($data);
            return self::sendResult(self::$okCode, $return);
        } catch (\Exception $e) {
            return self::sendResult(600, [], $e->getMessage());
        }
    }

    public function delPermissionCategory($ids)
    {
        try {
            $rbac = new RbacBase();
            $return = $rbac->delPermissionCategory($ids);
            return self::sendResult(self::$okCode, $return);
        } catch (\Exception $e) {
            return self::sendResult(600, [], $e->getMessage());
        }
    }

    public function getPermission($where)
    {
        try {
            $rbac = new RbacBase();
            $return = $rbac->getPermission($where);
            return self::sendResult(self::$okCode, $return);
        } catch (\Exception $e) {
            return self::sendResult(600, [], $e->getMessage());
        }
    }

    public function createPermission($data)
    {
        try {
            $rbac = new RbacBase();
            $return = $rbac->createPermission($data);
            return self::sendResult(self::$okCode, $return);
        } catch (\Exception $e) {
            return self::sendResult(600, [], $e->getMessage());
        }
    }

    public function delPermission($ids)
    {
        try {
            $rbac = new RbacBase();
            $return = $rbac->delPermission($ids);
            return self::sendResult(self::$okCode, $return);
        } catch (\Exception $e) {
            return self::sendResult(600, [], $e->getMessage());
        }
    }

    /**
     * 第一个参数支持传入id查询单条数据和标准的where表达式查询列表传为空数组则查询所有
     * 第二个参数选择是否查询角色分配的所有权限id默认为true
     * @param $where
     * @param bool $withPermissionId
     * @return array
     */
    public function getRole($where, $withPermissionId = true)
    {
        try {
            $rbac = new RbacBase();
            $return = $rbac->getRole($where, $withPermissionId);
            return self::sendResult(self::$okCode, $return);
        } catch (\Exception $e) {
            return self::sendResult(600, [], $e->getMessage());
        }
    }

    public function createRole($data, $idsStr)
    {
        try {
            $rbac = new RbacBase();
            $return = $rbac->createRole($data, $idsStr);
            return self::sendResult(self::$okCode, $return);
        } catch (\Exception $e) {
            return self::sendResult(600, [], $e->getMessage());
        }
    }

    public function delRole($ids)
    {
        try {
            $rbac = new RbacBase();
            $return = $rbac->delRole($ids);
            return self::sendResult(self::$okCode, $return);
        } catch (\Exception $e) {
            return self::sendResult(600, [], $e->getMessage());
        }
    }

    public function assignUserRole($id, $roleIds)
    {
        try {
            $rbac = new RbacBase();
            $return = $rbac->assignUserRole($id, $roleIds);
            return self::sendResult(self::$okCode, $return);
        } catch (\Exception $e) {
            return self::sendResult(600, [], $e->getMessage());
        }
    }

    /**
     * 删除缓存
     * @param $userId
     */
    public function delCache($userId)
    {
        // 删除旧的缓存数据缓存数据
        cache($this->_permissionCachePrefix . $userId, NULL);
    }

    public function setCache($userId, $newPermission = [], $timeOut = 3600)
    {
        Cache::set($this->_permissionCachePrefix . $userId, $newPermission, $timeOut);
    }

    public function setSession($userId)
    {
        Session::set($this->_sessionName, $this->_permissionCachePrefix . $userId);
    }

    /**
     * 更新权限缓存
     * @param $userId
     * @param int $timeOut
     * @return array|mixed|\PDOStatement|string|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function updateCache($userId, $timeOut = 3600)
    {
        if (empty($userId)) {
            return self::sendResult(600);
        }
        $permission = Cache::get($this->_permissionCachePrefix . $userId);
        if (!empty($permission)) {
            return $permission;
        }

        $permissionModel = new Permission('permission');
        $permission = $permissionModel->getPermissionByUserId($userId);

        if (empty($permission)) {
            return self::sendResult(600);
        }

        $newPermission = [];
        if (!empty($permission)) {
            foreach ($permission as $k => $v) {
                $newPermission[$v['path']] = $v;
            }
        }
        Cache::set($this->_permissionCachePrefix . $userId, $newPermission, $timeOut);
        return $newPermission;
    }

    /**
     * 更新权限
     * @param $userId
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function updatePermission($userId)
    {
        // 删除旧的缓存数据缓存数据
        $this->delCache($userId);
        // 重新授权
        $this->updateCache($userId);
        // 刷新菜单
        Menu::getAssignedMenu($userId, null, null, true);
    }
}